#pragma once

#include <iostream>
#include <string>
#include <queue>
#include <unistd.h>
#include <pthread.h>
#include "Cond.hpp"

// 单生产单消费
#define DEFAUTSIZE 5
template<class T>
class BlockQueue
{
private:
    bool Full()
    {
        return _cap == _task_queue.size();
    }
    bool Empty()
    {
        return _task_queue.size() == 0;
    }
public:
    BlockQueue(int cap = DEFAUTSIZE) : _prodoct_thread_size(0),_consumer_thread_size(0),_cap(cap)
    {}
    ~BlockQueue()
    {}
    void Enqueue(const T& task)
    {
        _mutex.lock();
        while(Full())
        {
            _cond_prodoct.wait(_mutex);
        }
        _task_queue.push(task);
        //通知
        _cond_consumer.notifyone();
        _mutex.unlock();
    }
    void Pop(const T* out)
    {
        _mutex.lock();
        while(Empty())
        {
            _cond_consumer.wait(_mutex);
        }
        *out = _task_queue.pop();
        _mutex.unlock();
    }
private:
    ConditionVal _cond_prodoct;
    ConditionVal _cond_consumer;
    Mutex _mutex;
    std::queue<T> _task_queue;
    int _prodoct_thread_size;
    int _consumer_thread_size;
    int _cap;
};